/* Sentinel - IRC Statistical and Operator Services
** init.c - Sentinel initialization functions
**
** Copyright W. Campbell and others.  See README for more details
** Some code Copyright: Jonathan George, Kai Seidler, ircd-hybrid Team,
**                      IRCnet IRCD developers.
**
** $Id: init.c 10 2010-02-02 01:12:49Z dubkat $
*/

#include "stats.h"
#include "struct.h"
#include "proto.h"
#include "slog.h"

#ifdef SUPPORT_MSG_UH
#ifdef STATSERV
char s_UH[MAXUSER + MAXHOST + 2];
#endif
#ifdef SPLITSERV
char sp_UH[MAXUSER + MAXHOST + 2];
#endif
#ifdef JUPESERV
char j_UH[MAXUSER + MAXHOST + 2];
#endif
#ifdef LISTSERV
char l_UH[MAXUSER + MAXHOST + 2];
#endif
char a_UH[MAXUSER + MAXHOST + 2];
#ifdef MONSERV
char m_UH[MAXUSER + MAXHOST + 2];
#endif
#endif

#ifdef SUPPORT_MSG_OPERS 
/* 7 is "opers@" and the \0 terminator
** I should PROBABLY force this to only be enabled on Hybrid 6
*/
char s_OPERS[MAXHOST + 7];
#endif

/* These are all horrible functions, peppered with ifdef's */

/* This is ugly, logging into each server type is slightly different */
int login()
{
  int ret; /* Check for write errors */
  time_t now = time(NULL);

#if defined(IRCD_HYBRID)
  ret = sts("PASS %s :TS", settings.pass);
  if (ret == 1)
    return 1;
  
  sts("SERVER %s 1 :%s", settings.name, settings.desc);
  sts("SVINFO 3 1 0 :%ld", CurrentTime);

#elif defined(IRCD_HYB6) || defined(IRCD_HYB7) || defined(IRCD_RATBOX) || defined(IRCD_HYBSVS)
	/* this will soon be a TS6 ONLY service! */
	#if defined(TS6) && (defined(IRCD_HYB7) || defined(IRCD_RATBOX))
		// sendto_one(client_p, "PASS %s TS %d :%s", server_p->spasswd, TS_CURRENT, me.id);
		slog(DEFAULT_LOG, L_DEBUG, "-> PASS %s TS 6 :%s", settings.pass, settings.sid);
		ret = sts("PASS %s TS 6 :%s", settings.pass, settings.sid );
	#else
		slog(DEFAULT_LOG, L_DEBUG, "-> PASS %s :TS", settings.pass);
		ret = sts("PASS %s :TS", settings.pass);
	#endif /* endif TS6 && hyb7/ratbox */

  if (ret == 1)
    return 1;
  slog(DEFAULT_LOG, L_DEBUG, "-> CAPAB :%s", me.capabs);
  sts("CAPAB :%s", me.capabs);
  
  slog(DEFAULT_LOG, L_DEBUG, "-> SERVER %s 1 :%s", settings.name, settings.desc);
  sts("SERVER %s 1 :%s", settings.name, settings.desc);
  
#if defined(TS6)
  slog(DEFAULT_LOG, L_DEBUG, "-> SVINFO 6 6 0 :%ld", now);
  sts("SVINFO 6 6 0 :%ld", now);
#else
  slog(DEFAULT_LOG, L_DEBUG, "-> SVINFO 5 3 0 :%ld", now);
  sts("SVINFO 5 3 0 :%ld", now);
#endif /*end TS6 */
  
#elif defined(IRCD_BAHAMUT)

  ret = sts("PASS %s :TS", settings.pass);
  if (ret == 1)
    return 1;
  /* Using SSJOIN will save bandwidth, UNCONNECT is required */
  sts("CAPAB :%s", me.capabs);
  sts("SERVER %s 1 :%s", settings.name, settings.desc);
  sts("SVINFO 3 1 0 :%ld", CurrentTime);
#endif

  return 0;
}

#ifdef MONSERV 
/* Bring up the monitor service */
void init_monserv()
{
  struct User *u = NULL;

  introduce_nick(MonServ.nick, MonServ.user, MonServ.host, MonServ.desc,
                 "io");

  u = AddUser(MonServ.nick, MonServ.user, MonServ.host, me.s, MonServ.desc);

  set_oper(u, UFLAG_ISOPER, OPER_MYOPER);

  u->flags |= UFLAG_INVIS;
  netinfo.invis++;
  u->server->invis++;

  MonServ.u = u;
}
#endif

#ifdef JUPESERV

/* Bring up the jupe service */
void init_jupeserv()
{
  struct User *u = NULL;

  introduce_nick(JupeServ.nick, JupeServ.user, JupeServ.host, JupeServ.desc,
                 "io");

  u = AddUser(JupeServ.nick, JupeServ.user, JupeServ.host, me.s, JupeServ.desc);

  set_oper(u, UFLAG_ISOPER, OPER_MYOPER);

  u->flags |= UFLAG_INVIS;
  netinfo.invis++;
  u->server->invis++;

  JupeServ.u = u;
}

#endif

#ifdef LISTSERV

/* Bring up the list service */
void init_listserv()
{
  struct User *u = NULL;

  introduce_nick(ListServ.nick, ListServ.user, ListServ.host, ListServ.desc,
                 "");

  u = AddUser(ListServ.nick, ListServ.user, ListServ.host, me.s, ListServ.desc);

  ListServ.u = u;
}

#endif

#ifdef STATSERV 
/* Init the StatServ client */
void init_statserv()
{
  struct User *u;

  introduce_nick(StatServ.nick, StatServ.user, StatServ.host, StatServ.desc,
                 IsStSetOper() ? "o" : "");

  u = AddUser(StatServ.nick, StatServ.user, StatServ.host, me.s, StatServ.desc);

  /* If the StatServ client is an oper, increase oper count here
  ** and set it as an oper
  */
  if (IsStSetOper())
  {
    set_oper(u, UFLAG_ISOPER, OPER_MYOPER);
  }
  StatServ.u = u;
}
#endif /* STATSERV */

#ifdef SPLITSERV 
/* Bring up the Split detecting/reporting client if it was enabled */
void init_splitserv()
{
  struct User *u;

  introduce_nick(SplitServ.nick, SplitServ.user, SplitServ.host, sp.desc, "");

  u = AddUser(SplitServ.nick, SplitServ.user, SplitServ.host,
              me.s, sp.desc);

  SplitServ.u = u;
}
#endif

/* Bring up the administration service */
void init_admin()
{
  struct User *u = NULL;

  introduce_nick(AdminServ.nick, AdminServ.user, AdminServ.host, AdminServ.desc,
                 "io");

  u = AddUser(AdminServ.nick, AdminServ.user, AdminServ.host, me.s,
              AdminServ.desc);

  set_oper(u, UFLAG_ISOPER, OPER_MYOPER);

  u->flags |= UFLAG_INVIS;
  netinfo.invis++;
  u->server->invis++;

  AdminServ.u = u;
}

#ifdef STATSERV 
/* Join the channel and obtain ops if it is a new channel
** We don't take over channels with Sentinel
*/
void init_join()
{
  dlink_node *dl;

  DLINK_FOREACH(dl, me.chan_list.head)
  {
    join_channel((char *) dl->data, StatServ.u, CMODE_OP);
  }
}
#endif

#ifdef SPLITSERV 
/* Join the channel and obtain ops if it is a new channel
** We don't take over channels with Split
*/
void init_spjoin()
{
  join_channel(sp.join_chan, SplitServ.u, CMODE_OP);
}
#endif

#ifdef PUBSTATS 
/* Join the channel and obtain ops if it is a new channel
** We don't take over channels with Sentinel
*/
void init_pubjoin()
{
  join_channel(settings.pub_chan, StatServ.u, CMODE_OP);
}
#endif

#ifdef ALERTMODE 
/* Join the channel and obtain ops if it is a new channel
** We don't take over channels with AdminServ...
** Though in this case we might want to.....
*/
void init_alert_join()
{
  join_channel(ALERTCHAN, AdminServ.u, CMODE_OP);
}
#endif

#ifdef DRONES_CHANNEL
void init_drone_join()
{
  join_channel(DRONES_CHANNEL, AdminServ.u, CMODE_OP);
}
#endif

#ifdef SPYMODE 
/* Join the channel and obtain ops if it is a new channel
** We don't take over channels with AdminServ...
** Though in this case we might want to.....
*/
void init_spy_join()
{
  join_channel(SPYCHAN, AdminServ.u, CMODE_OP);
}
#endif

void InitMessageStrings()
{
#ifdef SUPPORT_MSG_UH
  /* Create the user@host that we are to save some cycles later...
  ** IF this features is used often
  */
#ifdef STATSERV
  snprintf(s_UH, (MAXHOST + MAXUSER + 2), "%s@%s", StatServ.user,
           settings.name);
#endif
#ifdef SPLITSERV

  snprintf(sp_UH, (MAXHOST + MAXUSER + 2), "%s@%s", SplitServ.user,
           settings.name);
#endif

  snprintf(a_UH, (MAXHOST + MAXUSER + 2), "%s@%s", AdminServ.user,
           settings.name);
#ifdef MONSERV

  snprintf(m_UH, (MAXHOST + MAXUSER + 2), "%s@%s", MonServ.user,
           settings.name);
#endif
#ifdef JUPESERV

  snprintf(j_UH, (MAXHOST + MAXUSER + 2), "%s@%s", JupeServ.user,
           settings.name);
#endif
#ifdef LISTSERV

  snprintf(l_UH, (MAXHOST + MAXUSER + 2), "%s@%s", ListServ.user,
           settings.name);
#endif
#endif

#ifdef SUPPORT_MSG_OPERS
  /* Same as above...If we call it once, we'll definitely call it
  ** again...
  */
  snprintf(s_OPERS, (MAXHOST + 7), "opers@%s", settings.name);
#endif
}
